package com.hippoframework.bean;

import java.util.Map;

import com.hippoframework.bean.processor.ApplicationContextAwareProcessor;
import com.hippoframework.bean.processor.LifecycleBeanPostProcessor;
import com.hippoframework.config.Environment;
import com.hippoframework.config.EnvironmentRegistry;
import com.hippoframework.utils.ApplicationContextUtils;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

/**
 * 程序入口
 *
 * @author TylerW
 * @date 1/16/2020 2:30 PM
 */
@Slf4j
public class DefaultApplicationContext implements ApplicationContext {

    @Getter
    private final DefaultBeanFactory beanFactory;

    @Getter
    private final Environment environment;

    public DefaultApplicationContext() {
        log.info("init hippo-framework, version: alpha...");
        log.info("init application context...");

        environment = EnvironmentRegistry.createEnvironment();

        beanFactory = DefaultBeanFactory.init();
        beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
        beanFactory.addBeanPostProcessor(new LifecycleBeanPostProcessor());
        BeanRegistry.registerDefinition(beanFactory, environment);
        beanFactory.registerBeans();
        beanFactory.doPostProcessInit();

        ApplicationContextUtils.setApplicationContext(this);
    }

    @Override
    public <T> T getBean(String name, Class<T> requiredType) {
        return beanFactory.getBean(name, requiredType);
    }

    @Override
    public <T> T getBean(Class<T> requiredType) {
        return beanFactory.getBean(requiredType);
    }

    @Override
    public void doRegisterDefinition(Class<?> cls, GenericBeanDefinition definition) {
        beanFactory.doRegisterDefinition(cls, definition);
    }

    @Override
    public Map<String, BeanDefinition> getBeanDefinitions() {
        return beanFactory.getBeanDefinitions();
    }

}
